# coding=utf-8
from pandas import DataFrame
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import torch.nn as nn
import numpy as np
import torch
import pandas as pd
import os
import matplotlib.pyplot as plt


# 经纬度字符数据转浮点数
def int_to_float(data, columns_name):
    data[columns_name] = data[columns_name].apply(str)
    if columns_name == 'SJD' or columns_name == 'EJD':
        data[columns_name] = data[columns_name].apply(lambda x: float(x[:3] + '.' + x[3:]))
    elif columns_name == 'SWD' or columns_name == 'EWD':
        data[columns_name] = data[columns_name].apply(lambda x: float(x[:2] + '.' + x[2:]))
    return data[columns_name]


# 矩阵存为csv
def save_excel(m, path):
    df = DataFrame(m)
    df.to_csv(path)


# mean absolute relative error
def MARE(true, pred):
    diff = np.abs(true - pred)
    return np.sum(diff) / np.sum(np.abs(true))


# 模型评估
def validate(y, y_model):
    mae = mean_absolute_error(y, y_model)
    mse = mean_squared_error(y, y_model)
    y_model = y_model.reshape(y_model.shape[0])
    mare = MARE(y, y_model)
    r2 = r2_score(y, y_model)
    print('MAE:' + str(mae))
    print('MSE:' + str(mse))
    print('MARE:' + str(mare))
    print('R2:' + str(r2))
    return [mae, mse, mare, r2]
    # return [mae, mse, r2]


# 简易的embedding算法，有瑕疵
def embedding(col, target_dim):
    embeds = nn.Embedding(int(max(col)-min(col)+1), target_dim)
    tensor = embeds(torch.from_numpy(np.array(col - min(col))))
    return tensor.detach().numpy()


# 对特定列进行embedding并对数据划分训练集和测试集
def embed(data, split_date, embedding_cols, embedding_dims):
    embedding_result = [data]
    for col, dim in zip(embedding_cols, embedding_dims):
        embedding_result.append(pd.DataFrame(embedding(data[col].map(int), dim)))
    data = pd.concat(embedding_result, axis=1)

    train = data[data.month_day <= split_date]
    test = data[data.month_day > split_date]

    train = train.drop(embedding_cols, axis=1)
    test = test.drop(embedding_cols, axis=1)

    return train, test


# 将多维天气数据转换为四维
def weather_transform(data):
    data['climate_sunny'] = data['climate_clear']
    data['climate_cloudy'] = data['climate_partlycloudy'] + data['climate_scatteredclouds'] + data[
        'climate_mostlycloudy']
    data['climate_cloudy'] = data['climate_cloudy'].map(lambda x: 1 if x > 0 else 0)
    data['climate_rainy'] = data['climate_lightrainshowers'] + data['climate_lightrain'] + \
                            data['climate_rain'] + data['climate_rainshowers'] + data['climate_thunderstorm'] + \
                            data['climate_lightthunderstorms'] + data['climate_heavyrain']
    data['climate_rainy'] = data['climate_rainy'].map(lambda x: 1 if x > 0 else 0)
    drop_target = ['climate_clear', 'climate_partlycloudy', 'climate_scatteredclouds',
                   'climate_mostlycloudy', 'climate_lightrainshowers', 'climate_lightrain',
                   'climate_unknown', 'climate_rain',
                   'climate_rainshowers', 'climate_thunderstorm',
                   'climate_lightthunderstorms', 'climate_heavyrain']
    data = data.drop(drop_target, axis=1)

    return data


# 绘制拟合情况图
def draw_fix_fig(y_test, predicts, scalar):
    plt.plot([i+1 for i in range(len(y_test))], y_test*scalar)
    for predict in predicts:
        plt.plot([i+1 for i in range(len(y_test))], predict*scalar)
    plt.show()


# 加载厦门数据集
def load_xm(num, interval, time_chunk_size):
    max_longitude = 118.2007
    min_longitude = 118.0635
    max_latitude = 24.5664
    min_latitude = 24.4214
    month_length = 31
    file_path = './data/'
    # 判断是否预处理过
    if not os.path.exists(file_path + str(num) + '_' + str(interval) + 'business_step1.csv'):
        from preprocess.business_feature import business_step1, business_step2
        business_step1(num, max_longitude, min_longitude, max_latitude, min_latitude, interval)
        business_step2(num, interval, month_length, time_chunk_size)
    if not os.path.exists(file_path + str(num) + 'counts_POI.csv'):
        from preprocess.process_POI import poi_process
        poi_process(num, max_longitude, min_longitude, max_latitude, min_latitude)
    if not os.path.exists(file_path + 'weather_data.csv'):
        from preprocess.process_weather import weather_process
        weather_process()

    # 读取数据
    business = pd.read_csv(file_path + str(num) + '_' + str(interval) + 'business_final.csv')
    poi = pd.read_csv(file_path + str(num) + 'counts_POI.csv')
    weather = pd.read_csv(file_path + 'weather_data.csv')
    weather = weather_transform(weather)
    data = pd.merge(business, poi, how='left').fillna(0)
    data = pd.merge(data, weather, how='left', on=['month_day', 'hour']).fillna(0)
    business_step1 = pd.read_csv('./data/' + str(num) + '_' + str(interval) + 'business_step1.csv')
    scalar = max(business_step1['counts']) - min(business_step1['counts'])
    data = data.drop('date', axis=1)
    return data, scalar




